#pragma once

#include <memory>
#include "Alice/Log/Log.h"
#include "Alice/Core/World.h"
#include "Alice/Window/WindowMngr.h"
#include "Alice/Resource/ResourceMngr.h"
#include "Alice/Refl/ReflMngr.hpp"

namespace Alice
{

/*
    游戏状态
    用来强制要求 Init 函数的调用
    避免用户忘记初始化带来程序错误
*/
enum class GameState
{
    // 尚未初始化
    UNINIT,
    // 已被初始化
    INITED
};

class Game
{
public:
    Game();
    ~Game();

    /*
        初始化游戏资源
        \param window_info  用于创建窗口的信息
    */
    bool Init(WindowInfo window_info);

    /*
        开始游戏主循环
    */
    void Start();

    /*
        继续游戏
    */
    void Play();

    /*
        暂停游戏
    */
    void Pause();

    /*
        退出游戏主循环
    */
    void Quit();

    /*
        释放游戏资源
    */
    void Destroy();

    /*
        获取主要操作对象实例
        ResourceMngr 实例用来加载管理资源
        World 实例用来操作实体，管理事件
        ReflMngr 实例用来管理支持反射的数据
    */
    inline ResourceMngr* GetResourceMngr() { return m_res_mngr.get(); }
    inline World* GetWorld() { return m_world.get(); }
    inline ReflMngr* GetReflMngr() { return m_refl_mngr.get(); }

    /*
        获取窗口信息
    */
   inline WindowInfo GetWindowInfo() { return m_window_mngr->Info(); }

private:
    // Game 实例个数，用来限制用户创建多个 Game 实例
    static int s_count;
    // 控制游戏主循环
    bool m_looping;
    // 控制游戏是否暂停
    bool m_playing;
    // 当前游戏状态
    GameState game_state;
    std::unique_ptr<World> m_world;
    std::unique_ptr<WindowMngr> m_window_mngr;
    std::unique_ptr<ResourceMngr> m_res_mngr;
    std::unique_ptr<ReflMngr> m_refl_mngr;
};

} // namespace Alice
